package com.drd.dt.modular.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.drd.dt.common.Constant;
import com.drd.dt.common.SuccessResultEnum;
import com.drd.dt.common.tips.Tip;
import com.drd.dt.exception.BizExceptionEnum;
import com.drd.dt.exception.BussinessException;
import com.drd.dt.filter.UserThreadLocal;
import com.drd.dt.modular.dao.CommonMapper;
import com.drd.dt.modular.dao.OrderMapper;
import com.drd.dt.modular.dao.UserMapper;
import com.drd.dt.modular.dto.*;
import com.drd.dt.modular.entity.ImageConfig;
import com.drd.dt.modular.entity.User;
import com.drd.dt.modular.service.UserService;
import com.drd.dt.properties.ALYPropertyConfig;
import com.drd.dt.util.*;
import com.drd.dt.util.verify.Base64Utils;
import com.drd.dt.util.verify.DES;
import com.drd.dt.util.verify.SignUtil;
import org.apache.http.util.TextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 用户模块
 * 2019-10-33 th
 **/
@Transactional
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    private final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private CommonMapper commonMapper;
    @Autowired
    private JedisClient jedisClient;
    @Autowired
    private SMSUtil smsUtil;
    @Autowired
    private ALYPropertyConfig alyPropertyConfig;
    @Autowired
    private UserMoneyServiceImpl moneyService;
    @Autowired
    private UserMoneyServiceImpl testMoneyService;
    @Autowired
    private OrderMapper orderMapper;


    /**
     * 第三方微信登陆
     **/
    @Override
    public Tip thirdLogin(UserloginDTO userloginDTO, HttpServletRequest request) throws Exception {
        logger.info("【第三方微信登陆】" + userloginDTO.getWx_nickname() + " =" + userloginDTO.getUser_id() + " =" + userloginDTO.getThirdKey() + " =" + userloginDTO.getWx_openid());
        String key = "third_key_OU_A";
        String thirdKey = userloginDTO.getThirdKey();
        if (StringUtils.isEmpty(thirdKey)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        if (!thirdKey.equals(MD5Utils.MD5Encode(key, "UTF-8"))) {
            throw new BussinessException(BizExceptionEnum.USER_THIRD_KEY_ERROR);
        }
        Map<String, String> map = new HashMap<>();
        map.put("wxOpenid", userloginDTO.getWx_openid());
        //查询用户信息
        User user = userMapper.getByOpenId(map);
        String token = String.valueOf(System.currentTimeMillis());
        Integer user_id;
        JSONObject result = new JSONObject();
        if (null != user) {
            String phone = user.getPhone();
            if (StringUtils.isEmpty(phone)) {
                result.put("is_bind", 0);//是否绑定手机 1是 0否
            } else {
                result.put("is_bind", 0);//先都设置为未绑定，下版本在修改
                result.put("phone", phone);
            }
            Integer status = user.getStatus();
            Integer introducer = user.getIntroducer();
            if ((!StringUtils.isEmpty(status) && status == 2) || StringUtils.isEmpty(introducer)) {//账号未激活
                return ResultUtil.result(BizExceptionEnum.OT_WX_ILLEGAL.getCode(), BizExceptionEnum.OT_WX_ILLEGAL.getMessage(), result);
            }
            user_id = user.getId();
            result.put("user_id", user_id);
            User updateUser = new User();
            Integer id = user.getId();
            //  BeanUtils.copyProperties(userloginDTO, updateUser);
            updateUser.setId(id);
            updateUser.setToken(token);
            String nike_name = userloginDTO.getWx_nickname();
            updateUser.setNick_name(nike_name);
            updateUser.setWx_nickname(nike_name);
            updateUser.setDeviceT(userloginDTO.getDeviceT());
            updateUser.setSex(userloginDTO.getSex());
            updateUser.setApp_version(userloginDTO.getApp_version());
            updateUser.setHead_pic(userloginDTO.getHead_pic());
            result.put("token_id", token);
            updateUser.setRecent_login_time(Constant.y_M_d_H_m_s.format(new Date()));
            updateUser.setLastip(StringUtil.getIpAddr(request));
            String jp = user.getJp_id();
            String jp_id = userloginDTO.getJp_id();
            if (StringUtils.isEmpty(jp) || (!StringUtils.isEmpty(jp_id) && !jp_id.equals(jp))) {//用户的极光注册id为空时更新
                updateUser.setJp_id(jp_id);
            }
            userMapper.updateById(updateUser);
            result.put("friend_code", user.getFriend_code());
        } else {
            result.put("is_bind", 0);//是否绑定手机 1是 0否
            return ResultUtil.result(BizExceptionEnum.OT_WX_ILLEGAL.getCode(), BizExceptionEnum.OT_WX_ILLEGAL.getMessage(), result);
        }
        logger.info("【第三方微信登陆接口调用结束thirdLogin...】");
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 手机号登陆
     **/
    @Override
    public Tip codeLogin(HttpServletRequest request, UserloginDTO userloginDTO) throws Exception {
        logger.info("【开始手机号登陆接口codeLogin参数:UserloginDTO:" + userloginDTO + "...】");
        String phone = userloginDTO.getPhone();
        String smsCode = userloginDTO.getSmsCode();
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(smsCode)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        } else {
            //获取验证码
            String code = jedisClient.get("htsq:" + phone + "_code");
            if (!phone.equals("18782080836") && !phone.equals("18883278185") && !phone.equals("18617028583") &&
                    !phone.equals("16608055630") && !phone.equals("13600000000") && !phone.equals("15182269778") && !phone.equals("18381306487")) {
                if (StringUtils.isEmpty(code) || !smsCode.equals(code)) {
                    throw new BussinessException(BizExceptionEnum.USER_VALID_CODE_ERROR);
                }
            }
            String token = String.valueOf(System.currentTimeMillis());
            JSONObject result = new JSONObject();
            String ip = StringUtil.getIpAddr(request);
            Wrapper<User> wrapper = new EntityWrapper<>();
            wrapper.eq("phone", phone);
            List<User> users = userMapper.selectList(wrapper);
            if (users.size() < 1) {//不存在
                User user = new User();
                BeanUtils.copyProperties(userloginDTO, user);
                String wx_nickname = userloginDTO.getWx_nickname();
                String nickname = userloginDTO.getPhone();
                if (!StringUtils.isEmpty(wx_nickname)) {
                    nickname = wx_nickname;
                }
                user.setChannel_id(userloginDTO.getXd_id());
                user.setNick_name(nickname);
                user.setToken(token);
                user.setStatus(2);
                user.setCreate_time(Constant.y_M_d_H_m_s.format(new Date()));
                user.setLevel(0);
                user.setRecent_login_time(Constant.y_M_d_H_m_s.format(new Date()));
                user.setLastip(ip);
                String head_pic = user.getHead_pic();
                if (StringUtils.isEmpty(head_pic)) {//默认头像
                    ImageConfig imageS = commonMapper.getDefaultImg();
                    user.setHead_pic(imageS.getFile());
                }
                user.setPhone(phone);
                //新建用户
                userMapper.insert(user);
                Integer id = user.getId();
                user = new User();
                String friend_code = CodeUtils.toSerialCode(id);
                user.setId(id);
                user.setFriend_code(friend_code);
                userMapper.updateById(user);
                String vCode = getFriendCode(userloginDTO.getFriend_code(), request);
                result.put("friend_code", vCode);
                result.put("user_id", id);
                result.put("token_id", token);
                return ResultUtil.result(BizExceptionEnum.OT_PHONE_ILLEGAL.getCode(), BizExceptionEnum.OT_PHONE_ILLEGAL.getMessage(), result);
            } else {//用户存在
                Integer introducer = users.get(0).getIntroducer();
                Integer status = users.get(0).getStatus();
                Integer insertId = users.get(0).getId();
                String wx_openid = users.get(0).getWx_openid();
                String channel_id = users.get(0).getChannel_id();
                String friend_code = users.get(0).getFriend_code();
                String new_wx_openid = userloginDTO.getWx_openid();
                String xd_id = userloginDTO.getXd_id();
                result.put("user_id", insertId);
                if ((!StringUtils.isEmpty(status) && status == 2) || StringUtils.isEmpty(introducer)) {//账号未激活
                    String vCode = getFriendCode(userloginDTO.getFriend_code(), request);
                    result.put("friend_code", vCode);
                    return ResultUtil.result(BizExceptionEnum.OT_PHONE_ILLEGAL.getCode(), BizExceptionEnum.OT_PHONE_ILLEGAL.getMessage(), result);
                }
                User updateUser = new User();
                if (StringUtils.isEmpty(wx_openid) && !StringUtils.isEmpty(new_wx_openid)) {
                    updateUser.setWx_openid(new_wx_openid);
                }
                if (StringUtils.isEmpty(channel_id) && !StringUtils.isEmpty(xd_id)) {
                    updateUser.setChannel_id(xd_id);
                }
                updateUser.setId(insertId);
                updateUser.setToken(token);
                updateUser.setRecent_login_time(Constant.y_M_d_H_m_s.format(new Date()));
                updateUser.setLastip(ip);
                updateUser.setPhone(phone);//直接再次修改手机号，下个版本修改回去（微信登录已绑定手机号问题）
                if (!TextUtils.isEmpty(userloginDTO.getWx_nickname())) {
                    updateUser.setWx_nickname(userloginDTO.getWx_nickname());
                    updateUser.setNick_name(userloginDTO.getWx_nickname());
                }
                if (!TextUtils.isEmpty(userloginDTO.getHead_pic())) {
                    updateUser.setHead_pic(userloginDTO.getHead_pic());
                }
                String jp = users.get(0).getJp_id();
                String jp_id = userloginDTO.getJp_id();
                if (StringUtils.isEmpty(jp) || (!StringUtils.isEmpty(jp_id) && !jp_id.equals(jp))) {//用户的极光注册id为空时更新
                    updateUser.setJp_id(jp_id);
                }
                userMapper.updateById(updateUser);
                result.put("token_id", token);
                result.put("friend_code", friend_code);
                return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
            }
        }
    }

    /**
     * 秒验接口
     **/
    @Override
    public Tip verify(HttpServletRequest request,VerifyDTO verifyDTO) throws Exception {
        logger.info("【开始秒验接口verify()...】");
        final String appkey = "2d32ac59b5b40";//秒验的appkey
        final String appSecret = "7c64c917f44bbd7e8cbf8e9c8570d6ac";//秒验的appSecret
        JSONObject result = new JSONObject();

        String authHost = "http://identify.verify.mob.com/";
        String url = authHost + "auth/auth/sdkClientFreeLogin";
        HashMap<String, Object> param = new HashMap<>();
        String token1 = verifyDTO.getToken();
        String opToken = verifyDTO.getOpToken();
        String operator = verifyDTO.getOperator();
        param.put("appkey", appkey);
        param.put("token", token1);
        param.put("opToken", opToken);
        param.put("operator", operator);
        param.put("timestamp", System.currentTimeMillis());
        param.put("sign", SignUtil.getSign(param, appSecret));
//        String response = HttpConnectionPoolUtil.postRequestNoSecurity(url, null, param);
        String response = HttpConnectionPoolUtil.postCommandFromNet2(url, JSON.toJSONString(param));

        JSONObject resultData = JSONObject.parseObject(response);
        if (200 == resultData.getInteger("status")) {
            String res = resultData.getString("res");
            byte[] decode = DES.decode(Base64Utils.decode(res.getBytes()), appSecret.getBytes());
            resultData.put("res", JSONObject.parseObject(new String(decode)));
            logger.info("【秒验返回数据："+resultData+"】...");
        }
        String phone;
        if (resultData.containsKey("status") && resultData.getInteger("status") == 200){
            JSONObject res = resultData.getJSONObject("res");
            Integer isValid = res.getInteger("isValid");
            if (isValid == 1){//1:成功, 2:失败
                String return_phone = res.getString("phone");
                if (!StringUtils.isEmpty(return_phone)){
                    phone = return_phone;
                }else {
                    return ResultUtil.result(BizExceptionEnum.USER_MIAOYAN_ERROR.getCode(), BizExceptionEnum.USER_MIAOYAN_ERROR.getMessage(), result);
                }
            }else {
                return ResultUtil.result(BizExceptionEnum.USER_MIAOYAN_ERROR.getCode(), BizExceptionEnum.USER_MIAOYAN_ERROR.getMessage(), result);
            }
        }else {
            return ResultUtil.result(BizExceptionEnum.USER_MIAOYAN_ERROR.getCode(), BizExceptionEnum.USER_MIAOYAN_ERROR.getMessage(), result);
        }

        if (StringUtils.isEmpty(phone)){//手机号为空时
            return ResultUtil.result(BizExceptionEnum.USER_MIAOYAN_ERROR.getCode(), BizExceptionEnum.USER_MIAOYAN_ERROR.getMessage(), result);
        }
        String user_token = String.valueOf(System.currentTimeMillis());
        result.put("phone", phone);
        String ip = StringUtil.getIpAddr(request);
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("phone", phone);
        List<User> users = userMapper.selectList(wrapper);
        if (users.size() < 1) {//不存在
            User user = new User();
            BeanUtils.copyProperties(verifyDTO, user);
            String nickname = verifyDTO.getPhone();
            String wx_nickname = verifyDTO.getWx_nickname();
            if (!StringUtils.isEmpty(wx_nickname)) {
                nickname = wx_nickname;
            }
            user.setChannel_id(verifyDTO.getXd_id());
            user.setNick_name(nickname);
            user.setToken(user_token);
            user.setStatus(2);
            user.setCreate_time(Constant.y_M_d_H_m_s.format(new Date()));
            user.setLevel(0);
            user.setRecent_login_time(Constant.y_M_d_H_m_s.format(new Date()));
            user.setLastip(ip);
            String head_pic = user.getHead_pic();
            if (StringUtils.isEmpty(head_pic)) {//默认头像
                ImageConfig imageS = commonMapper.getDefaultImg();
                user.setHead_pic(imageS.getFile());
            }
            user.setPhone(phone);
            //新建用户
            userMapper.insert(user);
            Integer id = user.getId();
            user = new User();
            String friend_code = CodeUtils.toSerialCode(id);
            user.setId(id);
            user.setFriend_code(friend_code);
            userMapper.updateById(user);
            String vCode = getFriendCode(verifyDTO.getFriend_code(), request);
            result.put("user_id", id);
            result.put("friend_code", vCode);
            result.put("token_id", user_token);
            return ResultUtil.result(BizExceptionEnum.OT_PHONE_ILLEGAL.getCode(), BizExceptionEnum.OT_PHONE_ILLEGAL.getMessage(), result);
        } else {//用户存在
            Integer introducer = users.get(0).getIntroducer();
            Integer status = users.get(0).getStatus();
            Integer insertId = users.get(0).getId();
            String channel_id = users.get(0).getChannel_id();
            String wx_openid = users.get(0).getWx_openid();
            String friend_code = users.get(0).getFriend_code();
            String new_wx_openid = verifyDTO.getWx_openid();
            String xd_id = verifyDTO.getXd_id();
            result.put("user_id", insertId);
            if ((!StringUtils.isEmpty(status) && status == 2) || StringUtils.isEmpty(introducer)) {//账号未激活
                String vCode = getFriendCode(verifyDTO.getFriend_code(), request);
                result.put("friend_code", vCode);
                return ResultUtil.result(BizExceptionEnum.OT_PHONE_ILLEGAL.getCode(), BizExceptionEnum.OT_PHONE_ILLEGAL.getMessage(), result);
            }
            User updateUser = new User();
            if (StringUtils.isEmpty(wx_openid) && !StringUtils.isEmpty(new_wx_openid)) {
                updateUser.setWx_openid(new_wx_openid);
            }
            if (StringUtils.isEmpty(channel_id) && !StringUtils.isEmpty(xd_id)) {
                updateUser.setChannel_id(xd_id);
            }
            updateUser.setId(insertId);
            updateUser.setToken(user_token);
            updateUser.setRecent_login_time(Constant.y_M_d_H_m_s.format(new Date()));
            updateUser.setLastip(ip);
            updateUser.setPhone(phone);//直接再次修改手机号，下个版本修改回去（微信登录已绑定手机号问题）
            if (!TextUtils.isEmpty(verifyDTO.getWx_nickname())) {
                updateUser.setWx_nickname(verifyDTO.getWx_nickname());
                updateUser.setNick_name(verifyDTO.getWx_nickname());
            }
            if (!TextUtils.isEmpty(verifyDTO.getHead_pic())) {
                updateUser.setHead_pic(verifyDTO.getHead_pic());
            }
            String jp = users.get(0).getJp_id();
            String jp_id = verifyDTO.getJp_id();
            if (StringUtils.isEmpty(jp) || (!StringUtils.isEmpty(jp_id) && !jp_id.equals(jp))) {//用户的极光注册id为空时更新
                updateUser.setJp_id(jp_id);
            }
            userMapper.updateById(updateUser);
            result.put("token_id", user_token);
            result.put("friend_code", friend_code);
            return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
        }
    }

    /**
     * 智能匹配邀请码
     */
    private String getFriendCode(String validCode, HttpServletRequest request) {
        logger.info("【开始智能匹配邀请码getFriendCode参数:validCode:" + validCode + "...】");
        //根据ip和UA获取邀请码
        String friend_code = "";
        if (!StringUtils.isEmpty(validCode)) {//先获取剪切板的
            Wrapper<User> userWrapper = new EntityWrapper<>();
            userWrapper.eq("friend_code", validCode);
            List<User> userList = userMapper.selectList(userWrapper);
            if (userList.size() > 0) {
                friend_code = validCode;
            }
        } else {
            /*  String ip = StringUtil.getIpAddr(request);
            String user_agent = request.getHeader("User-Agent");
           String ua = StringUtil.getMobileByUA(user_agent);
           if (!StringUtils.isEmpty(ua)) {
                String ipCode = userMapper.getByUAAndIP(ip, ua);
                if (!StringUtils.isEmpty(ipCode)) {
                    friend_code = ipCode;
                }
            }else{
                String ipCode = userMapper.getByIP(ip);
                if (!StringUtils.isEmpty(ipCode)) {
                    friend_code = ipCode;
                }
            //}*/
        }
        return friend_code;
    }

    /**
     * 根据邀请码获取用户信息
     **/
    @Override
    public Tip codeInfo(String code) throws Exception {
        logger.info("【开始根据邀请码获取用户信息接口codeInfo参数:code:" + code + "...】");
        //判断用户是否存在 邀请码是否生效
        boolean matches = Pattern.matches("^[a-zA-Z]{6}$", code);
        if (StringUtils.isEmpty(code) || !matches) {
            throw new BussinessException(BizExceptionEnum.USER_FRIEND_CODE_ERROR);
        }
        Wrapper<User> userWrapper = new EntityWrapper<>();
        userWrapper.eq("friend_code", code.trim());
        List<User> userList = userMapper.selectList(userWrapper);
        if (userList.size() < 1) {
            throw new BussinessException(BizExceptionEnum.USER_FRIEND_CODE_NOT_EXIST);
        }
        User user = userList.get(0);
        Map result = new HashMap();
        String nick_name = user.getNick_name();
        String head_pic = user.getHead_pic();
        Integer status = user.getStatus();
        if (StringUtils.isEmpty(status) || status != 1) {//用户状态未激活
            throw new BussinessException(BizExceptionEnum.USER_FRIEND_CODE_NOT_EXIST);
        }
        if (StringUtils.isEmpty(head_pic)) {
            head_pic = "https://meimg.su.bcebos.com/htsq/htsq_icon.png";
        }
        if (StringUtils.isEmpty(nick_name)) {
            nick_name = "";
        }
        result.put("nick_name", EmojiUtil.decode(nick_name));
        result.put("head_pic", head_pic);
        logger.info("【根据邀请码获取用户信息接口调用完成codeBind】");
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 根据手机号绑定邀请码
     **/
    @Override
    public Tip codeBind(String code, String phone) throws Exception {
        logger.info("【开始根据手机号绑定邀请码接口codeBind参数:code:" + code + ",phone:" + phone + "...】");
        if (StringUtils.isEmpty(code) || code.length() != 6) {//验证码长度不为6
            throw new BussinessException(BizExceptionEnum.OT_USER_ERROR);
        }
        Wrapper<User> wrapper = new EntityWrapper();
        wrapper.eq("phone", phone);
        List<User> userList = userMapper.selectList(wrapper);
        if (userList.size() < 1) {
            throw new BussinessException(BizExceptionEnum.OT_USER_ERROR);
        }
        Integer introducer = userList.get(0).getIntroducer();
        JSONObject result = new JSONObject();
        if (!StringUtils.isEmpty(introducer)) {//邀请码已存在
            throw new BussinessException(BizExceptionEnum.USER_FRIENDCODE_IS_BIND);
        } else {
            User user = new User();
            Integer id = userList.get(0).getId();
            user.setId(id);
            Integer reCode = CodeUtils.codeToId(code);
            user.setIntroducer(reCode);
            user.setStatus(1);//账户激活
            userMapper.updateById(user);
            testMoneyService.updateUserFansNum(user);//更新粉丝数
            result.put("token_id", userList.get(0).getToken());
            result.put("user_id", userList.get(0).getId());
            result.put("friend_code", userList.get(0).getFriend_code());
        }
        logger.info("【根据手机号绑定邀请码接口调用结束codeBind...】");
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-用户信息
     **/
    @Override
    public Tip userInfo(Integer user_id, String token_id, String deviceT, String app_version, HttpServletRequest request) throws Exception {
        logger.info("【开始用户信息接口userInfo；参数user_id:" + user_id + ",token_id:" + token_id + ",deviceT:" + deviceT + ",app_version:" + app_version + "...】");
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        UserInfoDTO infoDTO = userMapper.getUserInfo(user_id);//获取用户信息

        if (!StringUtils.isEmpty(deviceT) && Integer.valueOf(deviceT) == 1) {//ios过审版
            infoDTO = filterIOSVersion(infoDTO, request, app_version);
        }

        UserInfoDTO estimate = userMapper.getUserTodayEstimate(user_id);//获取用户今日预估佣金、奖励金
        List<Map> banner = userMapper.getPersonalBanner();//获取个人中心banner图
        infoDTO.setBanner(banner);
        infoDTO.setToday_estimate_bounty(estimate.getToday_estimate_bounty());
        infoDTO.setToday_estimate_commission(estimate.getToday_estimate_commission());
        logger.info("【用户信息接口调用结束userInfo...】");
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), infoDTO);
    }

    /**
     * ios过审版本过滤
     */
    private UserInfoDTO filterIOSVersion(UserInfoDTO dto, HttpServletRequest request, String app_version) throws Exception {
        List<Map> littleIcon = new ArrayList<>();//个人中心 我的收益、订单、粉丝
        List<Map> bigIcon = new ArrayList<>();//个人中心 邀请好友、我的金币
        Map order = new HashMap();
        Map estimate = new HashMap();
        Map coin = new HashMap();
        order.put("title", "我的订单");
        order.put("url", "https://meimg.cdn.bcebos.com/htsq%2Fpersonal_icon%2Forder.png");
        estimate.put("title", "我的收益");
        estimate.put("url", "https://meimg.cdn.bcebos.com/htsq%2Fpersonal_icon%2Festimate.png");
        coin.put("title", "我的金币");
        coin.put("url", "https://meimg.cdn.bcebos.com/htsq%2Fpersonal_icon%2Fcoin.png");
        coin.put("desc", "金币兑换红包");
        littleIcon.add(order);
        littleIcon.add(estimate);
        //判断是否为国外ip
        String ip = StringUtil.getIpAddr(request);
        String country = new StringUtil().getIPLocation(ip);
        String version = userMapper.getVerifyVersion();//获取ios审核版本号
        if (!app_version.equals(version) && !country.equals("美国")) {//ios 审核版过滤
            Map fans = new HashMap();//我的粉丝
            Map rank = new HashMap();//粉丝英雄榜
            Map invite = new HashMap();//我的金币
            fans.put("title", "我的粉丝");
            fans.put("url", "https://meimg.cdn.bcebos.com/htsq%2Fpersonal_icon%2Ffans.png");
            rank.put("title", "粉丝英雄榜");
            rank.put("url", "https://meimg.cdn.bcebos.com/htsq%2Fpersonal_icon%2Frank.png");
            invite.put("title", "邀请好友");
            invite.put("url", "https://meimg.cdn.bcebos.com/htsq%2Fpersonal_icon%2Finvite.png");
            invite.put("desc", "邀请好友得奖励");
            littleIcon.add(fans);
            littleIcon.add(rank);
            bigIcon.add(invite);
            dto.setSaber(0);
        }
        bigIcon.add(coin);
        dto.setLittleIcon(littleIcon);
        dto.setBigIcon(bigIcon);
        return dto;
    }

    /**
     * 个人中心-修改用户信息
     **/
    @Override
    public Tip updateUser(UpdateUserInfoDTO userInfoDTO) throws Exception {
        User user = new User();
        BeanUtils.copyProperties(userInfoDTO, user);
        user.setId(userInfoDTO.getUser_id());
        userMapper.updateById(user);
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage());
    }

    /**
     * 个人中心-我的粉丝
     **/
    @Override
    public Tip myFans(Integer user_id, String token_id, Integer page, Integer type) throws Exception {
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        Integer pageSize = Constant.PAGE_SIZE_20;
        if (StringUtils.isEmpty(page)) {
            page = 1;
            pageSize = 2000;
        }
        if (StringUtils.isEmpty(type)) {
            type = 0;
        }
        JSONObject result = new JSONObject();
        String code = UserThreadLocal.get().getFriend_code();//当前用户的邀请码
        Integer introducer = UserThreadLocal.get().getIntroducer();
        Integer friend_code = CodeUtils.codeToId(code);
        PersonalCenterDTO user = userMapper.getPreAndMyInfo(CodeUtils.toSerialCode(introducer));//获取上级邀请人信息
        Integer direct_fans = 0;//直接粉丝数
        Integer indirect_fans = 0;//间接粉丝数
        Map map = userMapper.getUserFansNum(user_id);
        if (null != map) {
            direct_fans = Integer.valueOf(String.valueOf(map.get("direct_fans")));
            indirect_fans = Integer.valueOf(String.valueOf(map.get("indirect_fans")));
        }

        JSONObject superior = new JSONObject();//上级邀请人信息
        String head_pic = Constant.DEFAULT_HEAD_PIC;
        String nick_name = Constant.MSG_WX_NOT;
        String wx_num = Constant.MSG_WX_NOT;
        if (null != user) {
            head_pic = user.getHead_pic();
            nick_name = user.getNick_name();
            wx_num = user.getWx_num();
            if (StringUtils.isEmpty(wx_num)) {
                wx_num = Constant.MSG_WX_NOT;
            }
        }
        superior.put("head_pic", head_pic);
        superior.put("nick_name", nick_name);
        superior.put("wx_num", wx_num);

        Integer start = (page - 1) * pageSize;
        Integer size = start + pageSize;
        List<FansPageDTO> fansPage = new ArrayList<>();//存放分页后的数据
        List<PersonalCenterDTO> nextFans = userMapper.selectNextFans(friend_code);//获取直接},#{
        if (type == 0) {//所有粉丝
            Set<FansPageDTO> fans = new HashSet<>();
            List<FansPageDTO> directFans = JSON.parseArray(jedisClient.get("htsq:fans:" + user_id + ":direct"), FansPageDTO.class);
            List<FansPageDTO> indirectFans = JSON.parseArray(jedisClient.get("htsq:fans:" + user_id + ":indirect"), FansPageDTO.class);
            if (null != directFans && directFans.size() > 0) {
                fans.addAll(directFans);
            }
            if (null != indirectFans && indirectFans.size() > 0) {
                fans.addAll(indirectFans);
            }
            if (null != indirectFans && indirectFans.size() > size && page > 1) {//redis有数据
                start = (page - 2) * pageSize;
                fansPage = indirectFans.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            } else {//从数据库获取
                fansPage = selectNextFans(nextFans, user_id, start, pageSize, type, "fans", 0);
            }
        } else if (type == 1) {//直属粉丝
            List<FansPageDTO> directFans = JSON.parseArray(jedisClient.get("htsq:fans:" + user_id + ":direct"), FansPageDTO.class);
            if (null != directFans && directFans.size() > size && page > 1) {//redis有数据
                List<FansPageDTO> collect = directFans.stream().sorted(Comparator.comparing(FansPageDTO::getId).reversed()).collect(Collectors.toList());
                fansPage = collect.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            } else {//从数据库获取
                fansPage = selectNextFans(nextFans, user_id, start, pageSize, type, "fans", 0);
            }
        } else if (type == 2) {//间接粉丝
            List<FansPageDTO> indirectFans = JSON.parseArray(jedisClient.get("htsq:fans:" + user_id + ":indirect"), FansPageDTO.class);
            if (null != indirectFans && indirectFans.size() > size && page > 1) {//redis有数据
                fansPage = indirectFans.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            } else {//从数据库获取
                fansPage = selectNextFans(nextFans, user_id, start, pageSize, type, "fans", 0);
            }
        }

        List<PersonalCenterDTO> info = new ArrayList<>();
        if (null != fansPage && fansPage.size() > 0) {
            List<Integer> param = new ArrayList<>();
            fansPage.stream().forEach(t -> param.add(t.getId()));
            info = userMapper.selectPageFansInfo(param);
            for (FansPageDTO t : fansPage) {
                Integer id = t.getId();
                info.stream().forEach(p -> {
                    if (p.getId().equals(id)) {
                        p.setIs_direct(t.getT());
                    }
                });
            }
        }

        result.put("superior", superior);//上级邀请人信息
        result.put("allFans", info);//所有粉丝（直接粉丝和间接一二级粉丝）
        result.put("fansNum", direct_fans + indirect_fans);//总粉丝数量
        result.put("indirect_fans", indirect_fans);//间接粉丝数数量
        result.put("direct_fans", direct_fans);//直接粉丝数量

        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-我的粉丝（数据库分页）
     **/
    @Override
    public Tip myFansPage(Integer user_id, String token_id, Integer pageNum, Integer type,String time,String fans_num,String is_vip,String active) throws Exception {
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        Integer pageSize = Constant.PAGE_SIZE_20;
        if (StringUtils.isEmpty(pageNum)) {
            pageNum = 1;
            pageSize = 500;
        }
        if (StringUtils.isEmpty(type)) {
            type = 0;
        }
        if (StringUtils.isEmpty(time) && StringUtils.isEmpty(fans_num) &&
                StringUtils.isEmpty(is_vip) && StringUtils.isEmpty(active)) {
            time = "2";
        }
        JSONObject result = new JSONObject();
        String code = UserThreadLocal.get().getFriend_code();//当前用户的邀请码
        Integer introducer = UserThreadLocal.get().getIntroducer();
        Integer friend_code = CodeUtils.codeToId(code);
        PersonalCenterDTO user = userMapper.getPreAndMyInfo(CodeUtils.toSerialCode(introducer));//获取上级邀请人信息
        Integer direct_fans = 0;//直接粉丝数
        Integer indirect_fans = 0;//间接粉丝数
        Map map = userMapper.getUserFansNum(user_id);
        if (null != map) {
            direct_fans = Integer.valueOf(String.valueOf(map.get("direct_fans")));
            indirect_fans = Integer.valueOf(String.valueOf(map.get("indirect_fans")));
        }

        JSONObject superior = new JSONObject();//上级邀请人信息
        String head_pic = Constant.DEFAULT_HEAD_PIC;
        String nick_name = Constant.MSG_WX_NOT;
        String wx_num = Constant.MSG_WX_NOT;
        if (null != user) {
            nick_name = user.getNick_name();
            head_pic = user.getHead_pic();
            wx_num = user.getWx_num();
            if (StringUtils.isEmpty(wx_num)) {
                wx_num = Constant.MSG_WX_NOT;
            }
        }
        superior.put("head_pic", head_pic);
        superior.put("nick_name", nick_name);
        superior.put("wx_num", wx_num);

        Page page = new Page(pageNum,pageSize);
        List<PersonalCenterDTO> pageFans = new ArrayList<>();
        Date date = new Date();
        if (type == 0) {//所有粉丝
            List<Integer> ids = userMapper.selectRankNextIds(friend_code);//获取下级所有粉丝id
            pageFans = userMapper.selectPageAllMyFans(page,user_id,time,fans_num,is_vip,active);//分页获取全部粉丝
            pageFans.stream().forEach(t ->{
                Integer id = t.getId();
                String recent_login_time = t.getRecent_login_time();
                if (!StringUtils.isEmpty(recent_login_time)) {
                    String str = formatTime(recent_login_time, date);
                    t.setRecent_login_time(str);
                    ids.stream().forEach(p -> {
                        if (p.equals(id)) {
                            t.setIs_direct(1);
                        }
                    });
                }
            });
        } else if (type == 1) {//直属粉丝
            pageFans = userMapper.selectPageDirectMyFans(page,friend_code,time,fans_num,is_vip,active);//分页获取直属粉丝
            pageFans = getFormatTime(pageFans,date);
        } else if (type == 2) {//间接粉丝
            List<Integer> ids = userMapper.selectRankNextIds(friend_code);//获取下级所有粉丝id
            if (ids.size() < 1){
                ids.add(0);
            }
            pageFans = userMapper.selectPageNormalFans(page,user_id,ids,time,fans_num,is_vip,active);//分页获取间接粉丝
            pageFans = getFormatTime(pageFans,date);
        }

        result.put("superior", superior);//上级邀请人信息
        result.put("allFans", pageFans);//所有粉丝（直接粉丝和间接一二级粉丝）
        result.put("fansNum", direct_fans + indirect_fans);//总粉丝数量
        result.put("indirect_fans", indirect_fans);//间接粉丝数数量
        result.put("direct_fans", direct_fans);//直接粉丝数量

        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    private List<PersonalCenterDTO> getFormatTime(List<PersonalCenterDTO> pageFans,Date date){
        pageFans.forEach(t ->{
            String recent_login_time = t.getRecent_login_time();
            if (!StringUtils.isEmpty(recent_login_time)) {
                String str = formatTime(recent_login_time, date);
                t.setRecent_login_time(str);
            }
        });
        return pageFans;
    }

    /**
     * 分页获取我的下级粉丝
     */
    private List<FansPageDTO> selectNextFans(List<PersonalCenterDTO> nextFans, Integer user_id, Integer start, Integer pageSize, Integer type, String redisStr, Integer pType) {
        List<PersonalCenterDTO> allFans = new ArrayList<>();
        allFans.addAll(nextFans);
        Integer size = start + pageSize;//需要获取的数据大小
        Integer page = start / pageSize + 1;
        int directSize = allFans.size();//直粉数量
        if (type == 2) {//查普通粉丝
            directSize = 0;
        }
        if (directSize < size || page > 1) {//直粉数量小于查看数量，查间粉
            allFans.addAll(getDirectFans(nextFans, pType, size));//获取间接粉丝
        }
        //保存数据到redis
        List<FansPageDTO> directArr = new ArrayList<>();//直粉
        List<FansPageDTO> indirectArr = new ArrayList<>();//间粉
        allFans.stream().forEach(t -> {
            FansPageDTO dto = new FansPageDTO();
            Integer is_direct = t.getIs_direct();
            dto.setId(t.getId());
            dto.setM(t.getTotal_accumulated());
            dto.setT(t.getIs_direct());
            if (is_direct == 1) {
                directArr.add(dto);
            } else {
                indirectArr.add(dto);
            }
        });
        jedisClient.setWithExpire("htsq:" + redisStr + ":" + user_id + ":direct", JSON.toJSONString(directArr), 60 * 10);
        jedisClient.setWithExpire("htsq:" + redisStr + ":" + user_id + ":indirect", JSON.toJSONString(indirectArr), 60 * 10);
        List<FansPageDTO> fansPage = new ArrayList<>();//存放分页后的数据
        if (type == 0) {
            if (page == 1) {//第一页获取全部直属粉丝
                if (pageSize > 100) {//不传pageSize时，默认条数大于100时查所有
                    directArr.addAll(indirectArr);
                }
                fansPage = directArr;
            } else if (page > 1) {
                start = (page - 2) * pageSize;
                fansPage = indirectArr.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            } else {
                directArr.addAll(indirectArr);
                fansPage = directArr.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            }
        } else if (type == 1) {//直属粉丝
            if (pType == 1) {
                List<FansPageDTO> collect = directArr.stream().sorted(Comparator.comparing(FansPageDTO::getM).reversed()).collect(Collectors.toList());
                fansPage = collect.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            } else {
                List<FansPageDTO> collect = directArr.stream().sorted(Comparator.comparing(FansPageDTO::getId).reversed()).collect(Collectors.toList());
                fansPage = collect.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            }
        } else if (type == 2) {//普通粉丝
            fansPage = indirectArr.stream().skip(start).limit(pageSize).collect(Collectors.toList());
        }
        return fansPage;
    }

    /**
     * 个人中心-我的粉丝-粉丝详情
     **/
    @Override
    public Tip myFansInfo(Integer user_id, String token_id, Integer fans_id) throws Exception {
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id) || StringUtils.isEmpty(fans_id)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        FansInfoDTO infoDTO = userMapper.getMyFansInfo(fans_id);
        SimpleDateFormat sdf = Constant.y_M_d;
        String preMonthFirstDay = StringUtil.preMonthFirstDay(sdf);//上月第一天
        String preMonthLastDay = StringUtil.preMonthLastDay(sdf);//上月最后一天
        FansInfoDTO estimate = userMapper.getPreMonthEstimate(fans_id, preMonthFirstDay, preMonthLastDay);//获取累计和上月预估收益
        if (null != estimate) {
            infoDTO.setPre_month_accumulated(estimate.getPre_month_accumulated());
            infoDTO.setTotal_estimate(estimate.getTotal_estimate());
        }
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), infoDTO);
    }

    /**
     * 个人中心-我的订单
     **/
    @Override
    public Tip myOrders(Integer user_id, String token_id, Integer pageNum, Integer type, Integer status, Integer order_type) throws Exception {
        //订单类型 (1淘宝,2京东，3拼多多，4唯品会，5自营，6粉丝订单)
        //1普通订单 2礼包订单
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id) || StringUtils.isEmpty(pageNum)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        List<PersonalOrderDTO> order = new ArrayList<>();
        Page page = new Page(pageNum, Constant.PAGE_SIZE_20);
        if (null != type && type == 5) {
            order = userMapper.selectOwnOrder(page, user_id, status);//获取自营订单
        } else if (null != type && type == 6) {//粉丝订单
            if (null != order_type && order_type == 1) {//普通订单
                order = userMapper.selectFansOrder(page, user_id);
                order.stream().forEach(t -> t.setTitle(moneyService.getMessageText(t.getNick_name(), t.getCreate_time(), t.getRake_back(), 1)));
            } else if (null != order_type && order_type == 2) {//礼包订单
                order = userMapper.selectGiftOrder(page, user_id);
                order.stream().forEach(t -> t.setTitle(moneyService.getMessageText(t.getNick_name(), t.getCreate_time(), t.getRake_back(), 2)));
            }
        } else {
            order = userMapper.selectThirdOrder(page, user_id, status, type);//获取第三方订单
        }
        order.stream().forEach(t -> {
            if (t.getProduct_name().length() > 30) {
                t.setProduct_name(t.getProduct_name().substring(0, 30) + "...");
            }
        });
        page.setRecords(order);
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), page);
    }

    /**
     * 个人中心-龙虎榜（粉丝英雄榜）
     **/
    @Override
    public Tip rank(Integer user_id, String token_id, Integer page, Integer type) throws Exception {
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        Integer pageSize = Constant.PAGE_SIZE_20;
        if (StringUtils.isEmpty(page)) {
            page = 1;
            pageSize = 2000;
        }
        if (StringUtils.isEmpty(type)) {
            type = 0;
        }
        String code = UserThreadLocal.get().getFriend_code();
        Integer friend_code = CodeUtils.codeToId(code);
        List<PersonalCenterDTO> nextFans = userMapper.selectRankNextFans(friend_code);//获取下级所有粉丝

        Integer start = (page - 1) * pageSize;
        Integer size = start + pageSize;
        List<FansPageDTO> fansPage = new ArrayList<>();//存放分页后的数据
        if (type == 0) {//所有粉丝
            List<FansPageDTO> fans = new ArrayList<>();
            List<FansPageDTO> directFans = JSON.parseArray(jedisClient.get("htsq:rank:" + user_id + ":direct"), FansPageDTO.class);
            List<FansPageDTO> indirectFans = JSON.parseArray(jedisClient.get("htsq:rank:" + user_id + ":indirect"), FansPageDTO.class);
            if (null != directFans && directFans.size() > 0) {
                fans.addAll(directFans);
            }
            if (null != indirectFans && indirectFans.size() > 0) {
                fans.addAll(indirectFans);
            }
            if (null != indirectFans && indirectFans.size() > size && page > 1) {//redis有数据
//                List<FansPageDTO> collect = indirectFans.stream().sorted(Comparator.comparing(FansPageDTO::getM).reversed()).collect(Collectors.toList());
                start = (page - 2) * pageSize;
                fansPage = indirectFans.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            } else {//从数据库获取
                fansPage = selectNextFans(nextFans, user_id, start, pageSize, type, "rank", 1);
            }
        } else if (type == 1) {//直属粉丝
            List<FansPageDTO> directFans = JSON.parseArray(jedisClient.get("htsq:rank:" + user_id + ":direct"), FansPageDTO.class);
            if (null != directFans && directFans.size() > size && page > 1) {//redis有数据
                List<FansPageDTO> collect = directFans.stream().sorted(Comparator.comparing(FansPageDTO::getM).reversed()).collect(Collectors.toList());
                fansPage = collect.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            } else {//从数据库获取
                fansPage = selectNextFans(nextFans, user_id, start, pageSize, type, "rank", 1);
            }
        } else if (type == 2) {//间接粉丝
            List<FansPageDTO> indirectFans = JSON.parseArray(jedisClient.get("htsq:rank:" + user_id + ":indirect"), FansPageDTO.class);
            if (null != indirectFans && indirectFans.size() > size && page > 1) {//redis有数据
//                List<FansPageDTO> collect = indirectFans.stream().sorted(Comparator.comparing(FansPageDTO::getM).reversed()).collect(Collectors.toList());
                fansPage = indirectFans.stream().skip(start).limit(pageSize).collect(Collectors.toList());
            } else {//从数据库获取
                fansPage = selectNextFans(nextFans, user_id, start, pageSize, type, "rank", 1);
            }
        }

        List<PersonalCenterDTO> info = new ArrayList<>();
        if (null != fansPage && fansPage.size() > 0) {
            List<Integer> param = new ArrayList<>();
            fansPage.stream().forEach(t -> param.add(t.getId()));
            info = userMapper.selectPageRankFansInfo(param);
            for (FansPageDTO t : fansPage) {
                Integer id = t.getId();
                info.stream().forEach(p -> {
                    Integer pid = p.getId();
                    if (pid.equals(id)) {
                        p.setIs_direct(t.getT());
                    }
                });
            }
        }

        JSONObject result = new JSONObject();
        List<PersonalCenterDTO> collect = info.stream().sorted(Comparator.comparing(PersonalCenterDTO::getTotal_accumulated).reversed()).collect(Collectors.toList());
        result.put("allFans", collect);//所有粉丝（直接粉丝和间接一二级粉丝）

        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-龙虎榜（数据库分页）
     **/
    @Override
    public Tip rankPage(Integer user_id, String token_id, Integer pageNum, Integer type) throws Exception {
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        Integer pageSize = Constant.PAGE_SIZE_20;
        if (StringUtils.isEmpty(pageNum)) {
            pageNum = 1;
            pageSize = 500;
        }
        if (StringUtils.isEmpty(type)) {
            type = 0;
        }
        String code = UserThreadLocal.get().getFriend_code();
        Integer friend_code = CodeUtils.codeToId(code);

        Page page = new Page(pageNum, pageSize);
        List<PersonalCenterDTO> pageFans = new ArrayList<>();
        if (type == 0) {//所有粉丝
            List<Integer> ids = userMapper.selectRankNextIds(friend_code);//获取下级所有粉丝id
            pageFans = userMapper.selectPageAllFans(page, user_id);//分页获取全部粉丝
            pageFans.stream().forEach(t -> {
                Integer id = t.getId();
                ids.stream().forEach(p -> {
                    if (p.equals(id)) {
                        t.setIs_direct(1);
                    }
                });
            });
        } else if (type == 1) {//直属粉丝
            pageFans = userMapper.selectPageRankNextFans(page, friend_code);//分页获取直属粉丝
        } else if (type == 2) {//间接粉丝
            List<Integer> ids = userMapper.selectRankNextIds(friend_code);//获取下级所有粉丝id
            if (ids.size() < 1){
                ids.add(0);
            }
            pageFans = userMapper.selectPageRankNormalFans(page, user_id, ids);//分页获取间接粉丝
        }

        JSONObject result = new JSONObject();
        result.put("allFans", pageFans);

        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-我的收益
     **/
    @Override
    public Tip profit(Integer user_id, String token_id) throws Exception {
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        MyProfitDTO profitDTO = userMapper.getMyProfitInfo(user_id);//我的收益信息
        Map param = new HashMap();
        SimpleDateFormat y_m_d = Constant.y_M_d;
        param.put("user_id", user_id);
        param.put("yesterdayDay", StringUtil.yesterdayDay(y_m_d));
        param.put("thisMonthFirstDay", StringUtil.thisMonthFirstDay(y_m_d));
        param.put("thisMonthLastDay", StringUtil.thisMonthLastDay(y_m_d));
        param.put("preMonthFirstDay", StringUtil.preMonthFirstDay(y_m_d));
        param.put("preMonthLastDay", StringUtil.preMonthLastDay(y_m_d));
        MyProfitDTO result = new MyProfitDTO();
        MyProfitDTO historyProfit = userMapper.getHistoryProfit(param);//获取不同时间的预估收益
        if (null != historyProfit) {
            BeanUtils.copyProperties(historyProfit, result);
        }
        if (null != profitDTO) {
            result.setBalance(profitDTO.getBalance());
            result.setTotal_accumulated(profitDTO.getTotal_accumulated());
            result.setTotal_commission(profitDTO.getTotal_commission());
            result.setTotal_bounty(profitDTO.getTotal_bounty());
            result.setTotal_fans_num(profitDTO.getTotal_fans_num());
            result.setDirect_num(profitDTO.getDirect_num());
            result.setNormal_num(profitDTO.getNormal_num());
        }
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-邀请好友
     **/
    @Override
    public Tip invite(Integer user_id, String token_id, Integer deviceT, HttpServletRequest request) throws Exception {
        if (StringUtils.isEmpty(user_id) || StringUtils.isEmpty(token_id)) {
            throw new BussinessException(BizExceptionEnum.PARAM_EMPTY);
        }
        JSONObject result = new JSONObject();
        //客户端类型（Android:0  IOS:1）
        List<String> img = userMapper.selectInviteImg();//获取邀请好友的图片
        String friend_code = UserThreadLocal.get().getFriend_code();
        if (StringUtils.isEmpty(friend_code)) {
            friend_code = "";
        }
        String scheme = request.getScheme();
        String host = request.getServerName();
        int port = request.getServerPort();
        String downUrl = scheme + "://" + host + ":" + port + "/api/v2/htsq/user/scanQR?friend_code=" + friend_code;
        result.put("img", img);
        result.put("url", downUrl);
        result.put("friend_code", friend_code);
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-邀请好友-扫描二维码
     **/
    @Override
    public void scanQR(HttpServletResponse response, HttpServletRequest request, String friend_code) throws Exception {
        String agent = request.getHeader("User-Agent");
        /*if (!StringUtils.isEmpty(friend_code)) {
            Map map = new HashMap();
            String ip = StringUtil.getIpAddr(request);
            //String ua = StringUtil.getMobileByUA(agent);
           // String ua ="1";
            if (!StringUtils.isEmpty(agent)){
                map.put("ip", ip);
                map.put("friend_code", friend_code);
                map.put("user_agent", agent);
                map.put("create_time", Constant.y_M_d_H_m_s.format(new Date()));
                String code = userMapper.getByIP(ip);
                if (StringUtils.isEmpty(code)) {
                    userMapper.insertScanInfo(map);
                }

            }
        }*/
        String url = "https://a.app.qq.com/o/simple.jsp?pkgname=com.drd.hetaoshengqian&from=singlemessage";
        if (agent.contains("iPhone") || agent.contains("iPod") || agent.contains("iPad") || agent.contains("iOS")) {//ios
            url = "https://itunes.apple.com/cn/app/%E5%88%B8%E5%B7%B4%E5%A3%AB/id1472303484";
        }
        response.sendRedirect(url);
    }

    /**
     * 个人中心-常见问题-常见问题
     *
     * @return
     */
    @Override
    public Tip normalProblem() throws Exception {
        List<Map> result = userMapper.selectNormalProblem();
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-常见问题-问题分类 列表
     *
     * @return
     */
    @Override
    public Tip problemType() throws Exception {
        List<Map> result = userMapper.problemType();
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-常见问题-问题分类 答案
     *
     * @return
     */
    @Override
    public Tip problemList(Integer id) throws Exception {
        List<Map> result = userMapper.problemList(id);
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 个人中心-隐私政策
     **/
    @Override
    public Tip privacyPolicy() throws Exception {
        Map result = userMapper.getPrivacyPolicy();
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), result);
    }

    /**
     * 附值 用户下边 直属和普通粉丝状态
     *
     * @param nextFans
     * @paramt type 0 我的粉丝   1 龙虎榜
     */
    private List<PersonalCenterDTO> getDirectFans(List<PersonalCenterDTO> nextFans, int type, Integer size) {
        List<PersonalCenterDTO> indirectFans = new ArrayList<>();

        for (PersonalCenterDTO dto : nextFans) {
            int indirectFansSize = indirectFans.size();//间粉数量
            if (indirectFansSize >= size) {//间粉数量大于需要查询的数量时不再查询
                break;
            }
            getAllTest(indirectFans, dto, type);
        }
        return indirectFans;
    }

    private void getAllTest(List<PersonalCenterDTO> indirectFans, PersonalCenterDTO introducerDto, int type) {
        List<PersonalCenterDTO> childList = null;
        if (type == 0) {
            childList = userMapper.selectNextFans(introducerDto.getId());//获取直接所有粉丝
        } else if (type == 1) {
            childList = userMapper.selectRankNextFans(introducerDto.getId());//获取直接所有粉丝,里面有包括佣金
        }
        if (childList != null && childList.size() > 0) {
            for (PersonalCenterDTO dtome : childList) {
                dtome.setIs_direct(0);//普通
            }
            indirectFans.addAll(childList);
            for (PersonalCenterDTO dtome : childList) {
                getAllTest(indirectFans, dtome, type);
            }
        }
    }

    /**
     * 发短信获取验证码
     **/
    @Override
    public Tip sendVerificationCode(String phone) throws Exception {
        boolean mobileNO = StringUtil.isMobileNO(phone);
        if (!mobileNO) {
            throw new BussinessException(BizExceptionEnum.USER_PHONE_ERROR);
        } else {
            Integer sms = commonMapper.getSMSType();
            if (null == sms) {
                sms = 0;
            }
            String code = smsUtil.getSMSCode();
            //0 注册 1 忘记密码 2 三方登录绑定手机号
            if (smsUtil.clientReceiveSMS(phone, alyPropertyConfig.getAlyDlqrid(), code, sms)) {
                //加入缓存 60 秒
                jedisClient.setWithExpire("htsq:" + phone + "_code", code, 60);
            } else {
                throw new BussinessException(BizExceptionEnum.USER_MSG_SEND_FAIL);
            }

        }
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage());
    }

    /**
     * 获取个人会员信息
     */
    @Override
    public Tip getVipInfo(int user_id, String token_id) throws Exception {
        if (user_id < 0 || StringUtils.isEmpty(token_id)) {
            return ResultUtil.result(BizExceptionEnum.USER_ID_DISAPPEAR.getCode(), BizExceptionEnum.USER_ID_DISAPPEAR.getMessage());
        }
        Map<String, Object> map = userMapper.getThisFans(user_id);
        Map fans = userMapper.getUserFansNum(user_id);
        String direct_fans = "0";
        String normal_fans = "0";
        if (null != fans){
            direct_fans = String.valueOf(fans.get("direct_fans"));
            normal_fans = String.valueOf(fans.get("indirect_fans"));
        }
        String nike = map.get("nick_name").toString();
        map.put("nick_name", EmojiUtil.decode(nike));
        map.put("user_id",user_id);
        map.put("token_id",token_id);
        map.put("own_fans",direct_fans);
        map.put("normal_fans",normal_fans);
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), map);
    }

    /**
     * 检查用户是否有0元购权限
     *
     * @param user_id
     * @return
     * @throws Exception
     */
    @Override
    public Tip checkZeroPolicy(int user_id) throws Exception {
        if (user_id < 0) {
            return ResultUtil.result(BizExceptionEnum.USER_ID_DISAPPEAR.getCode(), BizExceptionEnum.USER_ID_DISAPPEAR.getMessage());
        }
        JSONObject obj = new JSONObject();
        long num = orderMapper.queryUserZeroNum(user_id);
        if (num < 1) {
            obj.put("allow", 1);
            obj.put("context", "具备0元购权限");
        } else {
            obj.put("allow", 0);
            obj.put("context", "您已使用过0元购福利，请关注更多活动");
        }
        return ResultUtil.result(SuccessResultEnum.SUCCESS.getCode(), SuccessResultEnum.SUCCESS.getMessage(), obj);
    }

    @Override
    public Tip vipLogin(HttpServletRequest request, Integer user_id, String phone, String code) throws Exception {
        //0 手机格式验证
        boolean mobileNO = StringUtil.isMobileNO(phone);
        if (!mobileNO) {
            throw new BussinessException(BizExceptionEnum.USER_PHONE_ERROR);
        }
        //1 验证码验证
        String redis_code = jedisClient.get("htsq:" + phone + "_code");
        if (!phone.equals("18782080836") && !phone.equals("18883278185") && !phone.equals("18617028583") &&
                !phone.equals("18617028583") && !phone.equals("13600000000") && !phone.equals("15182269778") && !phone.equals("18381306487")) {
            if (StringUtils.isEmpty(code) || ! code.equals(redis_code)) {
                throw new BussinessException(BizExceptionEnum.USER_VALID_CODE_ERROR);
            }
        }
        //1.1 判断是否存在该邀请人
        User introducerUser = userMapper.selectUserId(user_id);
        if (null == introducerUser) {
            throw new BussinessException(BizExceptionEnum.USER_ID_DISAPPEAR);
        }
        //2 是否存在该用户
        User user = userMapper.selectPhone(phone);
        int status = 2;
        Integer introducer;
        //2.1 存在  直接返回 用户信息
        if (null != user) {
            status = user.getStatus();
            introducer = user.getIntroducer();
            if ((!StringUtils.isEmpty(status) && status == 2) || StringUtils.isEmpty(introducer)) {//账号未激活
                //2.1.1 激活
                codeBind(introducerUser.getFriend_code(), phone);
            }
            Tip tip = getVipInfo(user.getId(), user.getToken());
            return tip;
        } else {
            //2.2 不存在 新键 绑定
            String token = String.valueOf(System.currentTimeMillis());
            String ip = StringUtil.getIpAddr(request);
            user = new User();
            user.setChannel_id("");
            user.setNick_name(phone);
            user.setToken(token);
            user.setStatus(3);
            user.setIntroducer(introducerUser.getId()); //推荐人id
            user.setCreate_time(Constant.y_M_d_H_m_s.format(new Date()));
            user.setLevel(0);
            user.setRecent_login_time(Constant.y_M_d_H_m_s.format(new Date()));
            user.setLastip(ip);
            ImageConfig imageS = commonMapper.getDefaultImg();
            user.setHead_pic(imageS.getFile());
            user.setPhone(phone);
            int reqin = userMapper.insert(user);
            if (reqin < 1) {
                throw new BussinessException(BizExceptionEnum.ADD_ERROR);
            }
            //2.2.1修改
            Integer id = user.getId();
            user = new User();
            String friend_code = CodeUtils.toSerialCode(id);
            user.setId(id);
            user.setFriend_code(friend_code);
            int requp = userMapper.updateById(user);
            if (requp < 1) {
                throw new BussinessException(BizExceptionEnum.UPDATE_ERROR);
            }
            Tip tip = getVipInfo(id,token);
            return tip;
        }
    }

    /**
     * 计算时间差
     */
    private static String formatTime(String beginTime,Date now){
        SimpleDateFormat simpleFormat = Constant.y_M_d_H_m_s;
        Date time = null;
        try {
            time = simpleFormat.parse(beginTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        long begin = time.getTime();
        long to1 = now.getTime();
         /*秒差*/
        long seconds = ((to1 - begin) / (1000));
         /*分钟差*/
        long minutes = seconds / 60;
        /*小时差*/
        long hours = minutes / 60;
        /*天数差*/
        long days = hours / 24;
        if (days <= 30){
            if (days < 1){
                days = 1;
            }
            return days + "天前";
        }
        /*月数差*/
        long months = days / 30;
        return months + "个月前";
    }
}
